package com.sawgdev.android.bokuiki.service;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.app.AlertDialog;
import android.app.Service;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.widget.Toast;

import com.sawgdev.android.bokuiki.bean.BeanHistory;
import com.sawgdev.android.bokuiki.common.Constants;
import com.sawgdev.android.bokuiki.common.Util;
import com.sawgdev.android.bokuiki.common.database.BKDBHelper;
import com.sawgdev.android.bokuiki.common.database.BkpfDao;

/**
 * GPS情報を監視し、DBに登録するためのServiceです。
 *
 * @author y-yamaguchi
 *
 */
public class SrvDokoiki extends Service implements LocationListener {

	private LocationManager locationManager;
	private Timer locationTimer;
	private long time;
	private Looper looper;


	@Override
	public void onDestroy() {
		// コールバック関数を削除
		locationManager.removeUpdates(this);
		Toast.makeText(this, "GPS Destroy!!", Toast.LENGTH_SHORT).show();
	}

	private void startLocationService() {
		stopLocationService();

		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		// 位置情報機能非搭載端末の場合
		if (locationManager == null) {
			return;
		}

		Criteria criteria = new Criteria();
		criteria.setBearingRequired(false); // 方位不要
		criteria.setSpeedRequired(false); // 速度不要
		criteria.setAltitudeRequired(false); // 高度不要

		final String provider = locationManager.getBestProvider(criteria, true);
		if (provider == null) {
			// 位置情報が有効になっていない場合は、Google Maps アプリライクな [現在地機能を改善] ダイアログを起動します。
			new AlertDialog.Builder(this)
					.setTitle("現在地機能を改善")
					.setMessage(
							"現在、位置情報は一部有効ではないものがあります。次のように設定すると、もっともすばやく正確に現在地を検出できるようになります:\n\n● 位置情報の設定でGPSとワイヤレスネットワークをオンにする\n\n● Wi-Fiをオンにする")
					.setPositiveButton("設定",
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(
										final DialogInterface dialog,
										final int which) {
									// 端末の位置情報設定画面へ遷移
									try {
										startActivity(new Intent(
												"android.settings.LOCATION_SOURCE_SETTINGS"));
									} catch (final ActivityNotFoundException e) {
										// 位置情報設定画面がない糞端末の場合は、仕方ないので何もしない
									}
								}
							})
					.setNegativeButton("スキップ",
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(
										final DialogInterface dialog,
										final int which) {
								} // 何も行わない
							}).create().show();

			stopLocationService();
			return;
		}

		// 最後に取得できた位置情報が5分以内のものであれば有効とします。
		final Location lastKnownLocation = locationManager
				.getLastKnownLocation(provider);
		if (lastKnownLocation != null
				&& (new Date().getTime() - lastKnownLocation.getTime()) <= (Constants.GPS_VALID_MINUTES * 60 * 1000L)) {
			setLocation(lastKnownLocation);
			return;
		}

		// Toast の表示と LocationListener の生存時間を決定するタイマーを起動します。
		locationTimer = new Timer(true);
		time = 0L;
		final Handler handler = new Handler(looper);
		locationTimer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				handler.post(new Runnable() {
					@Override
					public void run() {
						if (time == 1000L) {
							Toast.makeText(SrvDokoiki.this, "現在地を特定しています。",
									Toast.LENGTH_LONG).show();
						} else if (time >= (30 * 1000L)) {
							Toast.makeText(SrvDokoiki.this, "現在地を特定できませんでした。",
									Toast.LENGTH_LONG).show();
							stopLocationService();
						}
						time = time + 1000L;
					}
				});
			}
		}, 0L, 1000L);

		looper = Looper.getMainLooper();
		locationManager.requestLocationUpdates(provider, Constants.UPDAT_TIME,
				Constants.UPDAT_DISTANCE, this, looper);
	}

	private void stopLocationService() {
		if (locationTimer != null) {
			locationTimer.cancel();
			locationTimer.purge();
			locationTimer = null;
		}
		if (locationManager != null) {
			locationManager.removeUpdates(this);
			locationManager = null;
		}
	}

	private void setLocation(final Location location) {
		stopLocationService();

		// GPSの情報をDBに登録
		BeanHistory bean = new BeanHistory();
		bean.setLatitude(location.getLatitude());
		bean.setLongitude(location.getLongitude());
		bean.setAltitude(location.getAltitude());
		bean.setCreateDate(Util.getSystemDateStr());

		BkpfDao dao = new BkpfDao(BKDBHelper.getInstance(this)
				.getWritableDatabase());
		long result = dao.insHistory(bean);
		Toast.makeText(this, "GPS取得：" + result, Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		startLocationService();
	}

	@Override
	public void onLocationChanged(Location location) {
		setLocation(location);
	}

	@Override
	public void onProviderDisabled(String provider) {
	}

	@Override
	public void onProviderEnabled(String provider) {
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

}
